package com.cmii.sjw.department.control.jsc.service.impl;

import cn.dev33.satoken.secure.BCrypt;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaFoxUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cmii.sjw.department.control.common.RedisService;
import com.cmii.sjw.department.control.jsc.constant.Constants;
import com.cmii.sjw.department.control.jsc.mapper.LogininforMapper;
import com.cmii.sjw.department.control.jsc.mapper.UserMapper;
import com.cmii.sjw.department.control.jsc.model.Logininfor;
import com.cmii.sjw.department.control.jsc.model.User;
import com.cmii.sjw.department.control.jsc.model.vo.UserVo;
import com.cmii.sjw.department.control.jsc.service.UserRoleService;
import com.cmii.sjw.department.control.jsc.util.Result;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import jakarta.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 登录校验方法
 * @Author jfh
 * @Date 2024-11-13 周三 15:03
 * @Version 1.0
 */
@Component
public class LoginService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private RedisService redisService;

    @Resource
    private LogininforMapper logininforMapper;

    @Resource
    private UserRoleService userRoleService;
    /**
     * 验证码校验
     * @param code 验证码
     * @param uuid 验证码的uuid

//    @Value("${app.ip-whitelist}")
//    private List<String> ipWhitelist;

    /**
     * 登录校验
     * @param username 用户名
     * @param password 密码
     * @param code 验证码
     * @param uuid 验证码的uuid
     * @param clientIp 客户端IP
     * @return Result
     */
    public Result login(String username, String password, String code , String uuid,String clientIp) {

        // 验证IP是否在白名单中
//        if (!ipWhitelist.contains(clientIp)) {
//            return Result.error("IP地址不在白名单中");
//        }

        String captcha = validateCaptcha(code, uuid);
        // 验证码校验
        if ("expire".equals(captcha)){
            return Result.error("验证码到期");
        }else if ("error".equals(captcha)){
            return Result.error("验证码错误");
        }

        if (StringUtils.isEmpty(username)){
            return Result.error("用户名不能为空");
        }
        if (StringUtils.isEmpty(password)){
            return Result.error("密码不能为空");
        }

        //根据用户名从数据库中查询
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>()
                .eq(User::getUserName, username)
                .eq(User::getStatus, 0));
        if(user == null){
            return Result.error("用户名不存在");
        }
        // 使用checkpw方法检查被加密的字符串是否与原始字符串匹配：
        if(!BCrypt.checkpw(password, user.getPassword())){
            return Result.error("密码错误");
        }
        recordLoginInfo(user.getUserId(),clientIp);

        StpUtil.login(user.getUserId());
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
        // 返回值
        Map<String, Object> result = new HashMap<>();
        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(user,userVo);

        result.put("tokenInfo",tokenInfo);
        result.put("user",userVo);
        return Result.success("登录成功",result);
    }

    /**
     * 免验证登录
     * @param username
     * @param clientIp
     * @return
     */
    public Result unverifiedLogin(String username,String clientIp) {

        //根据用户名从数据库中查询
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>()
                .eq(User::getUserName, username)
                .eq(User::getStatus, 0)
        );
        if(user == null){
            return Result.error("用户名不存在");
        }
        recordLoginInfo(user.getUserId(),clientIp);

        StpUtil.login(user.getUserId());
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
        Map<String, Object> result = new HashMap<>();

        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(user,userVo);

        result.put("tokenInfo",tokenInfo);
        result.put("user",userVo);
        return Result.success("登录成功",result);
    }

    /**
     * 用户注册
     * @param username 用户名
     * @param password 密码
     * @return Result
     */
    public Result register(String username, String password) {
        // 检查用户名是否已存在
        User existingUser = userMapper.selectOne(new LambdaQueryWrapper<User>()
                .eq(User::getUserName, username));
        if (existingUser != null) {
            return Result.error("用户名已存在");
        }

        // 使用 BCrypt 加密密码
        String hashedPassword = BCrypt.hashpw(password, BCrypt.gensalt());

        // 创建新用户
        User newUser = new User();
        newUser.setUserName(username);
        newUser.setNickName(SaFoxUtil.getRandomString(20));
        newUser.setPassword(hashedPassword);
        newUser.setStatus("0"); // 默认状态为正常

        // 保存用户到数据库
        userMapper.insert(newUser);

        return Result.success("注册成功");
    }

    /**
     * 修改用户密码
     * @param userId 用户ID
     * @param oldPassword 旧密码
     * @param newPassword 新密码
     * @return Result
     */
    public Result changePassword(long userId, String oldPassword, String newPassword) {
        // 根据用户ID从数据库中查询用户信息
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>()
                .eq(User::getUserId, userId)
                .eq(User::getStatus, 0));
        if (user == null) {
            return Result.error("用户不存在");
        }

        // 校验旧密码是否正确
        if (!BCrypt.checkpw(oldPassword, user.getPassword())) {
            return Result.error("旧密码错误");
        }

        // 使用 BCrypt 加密新密码
        String hashedPassword = BCrypt.hashpw(newPassword, BCrypt.gensalt());

        userMapper.update(new User().setPassword(hashedPassword), new LambdaQueryWrapper<User>().eq(User::getUserId, userId));

        return Result.success("密码修改成功");
    }

    /**
     * 校验验证码
     * @param code
     * @param uuid
     * @return
     */

    public String validateCaptcha(String code, String uuid) {
        String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
        String captcha = redisService.get(verifyKey,String.class);
        if (captcha == null) {
            return "expire";
        }
        redisService.delete(verifyKey);
        if (!code.equalsIgnoreCase(captcha)) {
            return "error";
        }
        return "success";
    }

    /**
     * 记录登录信息
     *
     * @param userId 用户ID
     * @param clientIp 客户端IP
     */
    public void recordLoginInfo(Long userId,String clientIp)
    {
        User sysUser = new User();
        sysUser.setLoginIp(clientIp);
        sysUser.setLoginDate(new Date());
        userMapper.update(sysUser, new LambdaQueryWrapper<User>().eq(User::getUserId, userId));
    }

    /**
     * 记录系统访问日志
     * @param userId 用户ID
     * @param clientIp 客户端IP
     * @param action 操作类型（登录成功/退出成功）
     */
    public void recordAccessLog(Long userId, String clientIp, String action) {
        //根据用户名从数据库中查询
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>()
                .eq(User::getUserId, userId)
                .eq(User::getStatus, 0));

        // 创建访问日志记录
        Logininfor accessLog = new Logininfor();
        accessLog.setUserName(user.getUserName());
        accessLog.setIpaddr(clientIp);
        accessLog.setMsg(action);
        accessLog.setLoginTime(new Date());

        // 保存访问日志到数据库
        logininforMapper.insert(accessLog);
    }


}
